#include<iostream>
#include<assert.h>
#include<vector>
using namespace std;
namespace hcc
{
    template<class T>
        class vector
        {
            public:
                typedef T* iterator;
                vector()
                    : _start(nullptr)
                    , _finish(nullptr)
                    , _capacity(nullptr)
                    {}
                vector(iterator begin,iterator last)
                    : _start(nullptr)
                    , _finish(nullptr)
                    , _capacity(nullptr)
                {
                    while(begin!=last)
                    {
                        push_back(*begin);
                        begin++;
                    }
                }
                vector(const vector& d)
                    : _start(nullptr)
                    , _finish(nullptr)
                    , _capacity(nullptr)
                {
                    vector<T> tem(d.begin(),d.end());
                    swap(tem);
                }
                vector<T>& operator=(vector<T> d)
                {
                    swap(d);
                    return *this;
                }
                ~vector()
                {
                    delete[] _start;
                    _start=_finish=_capacity=nullptr;
                }
                iterator begin()
                {
                    return _start;
                }
                iterator end()
                {
                    return _finish;
                }
                const iterator begin()const
                {
                    return _start;
                }
                const iterator end()const 
                {
                    return _finish;
                }
                void swap(vector<T>& d)
                {
                    std::swap(_start,d._start);
                    std::swap(_finish,d._finish);
                    std::swap(_capacity,d._capacity);
                }
                size_t size()const
                {
                    return _finish-_start;
                }
                size_t capacity()const
                {
                    return _capacity-_start;
                }
                void resize(size_t x,const T& x=T())
                {
                    reserve(x);
                    _finish+=x;
                    int i=0;
                    while(i<(int)size())
                    {
                        _start[i++]=x;
                    }
                }
                void reserve(size_t x)
                {
                    if(_start==nullptr)
                    {
                        _start=new T[x];
                        _finish=_start;
                        _capacity=_start+x;
                    }
                    if(x>(_capacity-_start))
                    {
                        size_t ret=size();
                        T* tem=new T[x];
                        for(size_t i=0;i<x;i++)
                            tem[i]=_start[i];
                        std::swap(tem,_start);
                        _start=tem;
                        _finish=_start+ret;
                        _capacity=_start+x;
                    }
                }
                void push_back(const T& x)
                {
                    // if(_start==nullptr)
                    // {
                    //     _start=new T[4];
                    //     _finish=_start;
                    //     _capacity=_start+4;
                    // }
                    // if(size()==capacity())
                    // {
                    //     reserve(2*capacity());
                    // }
                    // _start[_finish-_start]=x;
                    // _finish++;
                    insert(_start+size(),x);
                }
                T& operator[](size_t x)const
                {
                    assert(x<size());
                    return _start[x];
                }
                T& back()const
                {
                    return _start[size()];
                }
                T& front()const
                {
                    return _start[0];
                }
                void pop_back()
                {
                    _finish--;
                }
                iterator insert(iterator pos,const T& x)
                {
                    if(_start==nullptr)
                    {
                        _start=new T[4];
                        _finish=_start;
                        _capacity=_start+4;
                        pos=_start;
                    }
                    if(size()==capacity())
                        reserve(2*capacity());
                    size_t ret=pos-_start;
                    size_t i=size();
                    while(i!=0&&i>=ret)
                    {
                        _start[i+1]=_start[i];
                        i--;
                    }
                    *pos=x;
                    _finish++;
                    return pos;
                }
                iterator erase(iterator pos)
                {
                    size_t ret=pos-_start;
                    while(ret+1<size())
                    {
                        _start[ret]=_start[ret+1];
                        ret++;
                    }
                    _finish--;
                    return pos;
                }
            private:
                iterator _start;
                iterator _finish;
                iterator _capacity;
        };
}
